import re

from django.contrib.auth.backends import ModelBackend
from itsdangerous import BadData

from apps.users.models import User
from meiduo_mall import settings

"""
代码的抽取/封装
1.为什么要抽取代码
    代码抽取,降低代码耦合度,代码的复用(需求变更,可以只改一个地方)
2.什么时候抽取代码
    某些行(1,n行)代码实现了一个小功能
    当你复制重复(第二次)代码的时候就要考虑是否抽取
3.如何实现
    县定义一个函数()方法,函数名无所谓,也不用关心参数
    将要抽取的代码拷贝到这个函数中,哪里有问题改哪里,
    没有的变量已参数的形式传递验证,验证没有问题之后,再将源代码删除
"""


def get_user_by_username(username):
    # 函数功能,传递用户信息,返回user
    try:
        if re.match('^1[3-9]\d{9}$', username):
            # 手机号登录
            user = User.objects.get(mobile=username)
        # elif邮箱
        else:
            # 用户名登录
            user = User.objects.get(username=username)
    except User.DoesNotExist:
        return None
    # 记得返回user
    return user
class UsernameMobileModelBackend(ModelBackend):
    """自定义用户认证后端

    1.用户名或手机号登录,系统默认的是用户名
    当系统不满足需求时,我们就继承重写
    2.
    """

    def authenticate(self, request, username=None, password=None, **kwargs):
        # username 有可能是用户名或手机号
        # 若是用户名,就根据用户名查询
        # 若是手机号,就根据手机号查询

        # 根据正则来区分手机号
        # 1.区分用户名手机号,查出用户
        # try:
        #     if re.match('^1[3-9]\d{9}$', username):
        #         # 手机号登录
        #         user = User.objects.get(mobile=username)
        #     else:
        #         # 用户名登录
        #         user = User.objects.get(username=username)
        # except User.DoesNotExist:
        #     return None

        user = get_user_by_username(username)
        # 2.根据用户信息验证密码,user有为None的时候
        if user is not None and user.check_password(password):
            return user

        # request.user.is_authenticated
        # is_authenticated判断用户是否登陆
        # 如果登录就返回True
        # 如果没有登录就返回Ｆａｌｓｅ

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer,SignatureExpired,BadData

# from meiduo_mall import settings
def generic_verify_email_url(user_id):

    #1.创建实例对象
    s = Serializer(secret_key=settings.SECRET_KEY,expires_in=3600)
    #2.组织数据
    data = {
        'user_id':user_id
    }
    #3.加密数据
    token = s.dumps(data)
    #4.返回数据
    return  settings.EMAIL_VERIFY_URL + '?token=' + token.decode()

def check_verify_email_token(token):

    #1.创建实例对象
    s = Serializer(secret_key=settings.SECRET_KEY, expires_in=3600)
    #2.对数据进行解密,解密的时候可能有异常
    try:
        result = s.loads(token)
    except BadData:
        return None
    #3.返回数据
    return result.get('user_id')
